#from enum import * #@UnusedWildImport
from chordsparser import * #@UnusedWildImport
from chord import * #@UnusedWildImport

#STRING = enum ('E_UPPER_1', 'B_2', 'G_3', 'D_4', 'A_5', 'E_LOWER_6')
STRING_NOTES = ['E', 'B', 'G', 'D', 'A', 'E']
#Ich weisse das sheisse ist
CHORDS = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
NO_STEP = 0


class Tabulature(object):

    def __init__(self, chordString):
        chord = ChordsParser(chordString).getChord()
        self.strings = list()
        self.strings.append (TabLine('E', chord))
        self.strings.append (TabLine('B', chord))
        self.strings.append (TabLine('G', chord))
        self.strings.append (TabLine('D', chord))
        self.strings.append (TabLine('A', chord))
        self.strings.append (TabLine('E', chord))

    def printTab(self):
        for tabLine in self.strings:
            print TabView.apply(tabLine, 0, 7)
            
    def printPermutations(self):
        eSteps = self.strings[0].getStepPositions(0, 5).items()
        aSteps = self.strings[1].getStepPositions(0, 5).items()
        dSteps = self.strings[2].getStepPositions(0, 5).items()
        gSteps = self.strings[3].getStepPositions(0, 5).items()
        bSteps = self.strings[4].getStepPositions(0, 5).items()
        elowSteps = self.strings[5].getStepPositions(0, 5).items()
        
        for ekey, evalue in eSteps:
            for akey, avalue in aSteps:
                for dkey, dvalue in dSteps:
                    for gkey, gvalue in gSteps:
                        for bkey, bvalue in bSteps:
                            for elowkey, elowvalue in elowSteps:
                                print "".join ([str(elowvalue), str(bvalue), str(gvalue), str(dvalue), str(avalue), str(evalue)])
        
        
        
class TabLine(object):
    
    def __init__(self, index, chord):
        self.stringKey=index         
        self.chord = chord
    
    def getStep(self):
        return self.chord.getStepFor(self.stringKey)
    #returns list of numbers, len =endFret-startFret
    #0 - means the note not in the chord
    #number - step in the chord
    #startFret == 0 means from 1st fret    
    def getFrets(self, startFret, endFret):
        #TODO add this stuff
        if endFret > len(CHORDS):
            raise Exception ("Cmon, you cannot make that wide. Not supported yet.")
         
        shift = CHORDS.index(self.stringKey) + 1 #string key is not included
        result = list()
        for index in range(startFret, endFret + 1):
            #move by C - key
            #TODO test
            indexInC = shift + index
            while not indexInC < len(CHORDS):
                indexInC = indexInC - len(CHORDS)
            
            note = CHORDS[indexInC]
            if self.chord.containsNote (note):
                result.append (self.chord.getStepFor (note))
            else:
                result.append (NO_STEP)
        return result
    
    def getStepPositions(self, start, end):
        frets = self.getFrets (start, end)
        result = dict()
        if self.chord.containsNote (self.stringKey):
            result [self.chord.getStepFor (self.stringKey)] = 0 
        index = 1    
        for fret in frets:
            if fret != 0:
                result [fret] = index
            index = index + 1
        return result
    
class TabView:
    @staticmethod
    def apply(tabLine, start, end):
        frets = tabLine.getFrets (start, end)
        keyStep = tabLine.getStep()
        result = list(tabLine.stringKey + '|')
        if (keyStep == -1):
            result.append('X')
        else:
            result.append (str(keyStep))
        result.append("|") 
        for value in frets:
            if value == 0:
                result.append("-")
            else:
                result.append(str(value))
        return "".join(result)
    
    